package com.linkwechat.util;

import com.alibaba.fastjson.JSONObject;
import com.linkwechat.common.dto.qw.SetAuthConfigDTO;
import com.linkwechat.common.utils.JsonUtil;
import com.linkwechat.common.utils.ParamCheckUtil;
import com.linkwechat.common.utils.StringUtil;
import com.linkwechat.common.utils.UrlUtil;
import com.linkwechat.common.utils.http.HttpUtil;
import com.linkwechat.common.vo.qw.*;
import com.linkwechat.domain.wecom.vo.department.QwDeptListVO;
import com.linkwechat.domain.wecom.vo.user.QwDeptUserVO;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 *
 *
 * https://blog.csdn.net/IUTStar/article/details/134269268
 */
@Slf4j
public class QYWXUtil {

    public static Logger logger = LoggerFactory.getLogger(QYWXUtil.class);

    /**
     * https://developer.work.weixin.qq.com/document/path/90600
     */
    private static final String GET_SUITE_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/service/get_suite_token";

    /**
     * https://developer.work.weixin.qq.com/document/path/90601
     */
    private static final String GET_PRE_AUTH_CODE_URL = "https://qyapi.weixin.qq.com/cgi-bin/service/get_pre_auth_code?suite_access_token=";

    /**
     * https://developer.work.weixin.qq.com/document/path/90602
     */
    private static final String SET_AUTH_CONFIG_URL = "https://qyapi.weixin.qq.com/cgi-bin/service/set_session_info?suite_access_token=";

    /**
     * https://developer.work.weixin.qq.com/document/path/90603
     */
    private static final String GET_ENTERPRISES_PERMANENT_AUTH_CODE_URL = "https://qyapi.weixin.qq.com/cgi-bin/service/get_permanent_code?suite_access_token=";

    /**
     * https://developer.work.weixin.qq.com/document/path/90606
     */
    private static final String GET_APP_ADMIN_LIST_URL = "https://qyapi.weixin.qq.com/cgi-bin/service/get_admin_list?suite_access_token=";

    /**
     * https://developer.work.weixin.qq.com/document/path/91121
     */
    private static final String GET_VISIT_USER_URL = "https://qyapi.weixin.qq.com/cgi-bin/service/auth/getuserinfo3rd?suite_access_token=%s&code=%s";

    /**
     * https://developer.work.weixin.qq.com/document/path/90605
     */
    private static final String GET_QY_ACCESS_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/service/get_corp_token?suite_access_token=";


    /**
     * https://developer.work.weixin.qq.com/document/24364
     * 企业的
     */
    private static final String GET_QYWX_QY_JSAPI_TICKET_URL = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=%s";


    /**
     * https://developer.work.weixin.qq.com/document/24364#%E8%8E%B7%E5%8F%96%E5%BA%94%E7%94%A8%20jsapi_ticket
     * 应用的
     */
    private static final String GET_QYWX_APP_JSAPI_TICKET_URL = "https://qyapi.weixin.qq.com/cgi-bin/ticket/get?access_token=%s&type=agent_config";

    /**
     * https://developer.work.weixin.qq.com/document/path/91039
     */
    private static final String QYWX_ACCESS_TOKEN_UTL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s";

    /**
     * https://developer.work.weixin.qq.com/document/path/94661
     * 客服列表
     */
    private static final String QYWX_KF_ACCOUNT_LIST_URL = "https://qyapi.weixin.qq.com/cgi-bin/kf/account/list?access_token=%s";

    /**
     * https://developer.work.weixin.qq.com/document/path/94670
     * 获取客服消息
     */
    private static final String QYWX_FK_SYNC_MSG_URL = "https://qyapi.weixin.qq.com/cgi-bin/kf/sync_msg?access_token=%s";

    public static SuiteTokenVO getSuiteAccessToken(String suiteId, String suiteSecret, String suiteTicket) {
        Map<String,String> params = new HashMap<>();
        params.put("suite_id",suiteId);
        params.put("suite_secret",suiteSecret);
        params.put("suite_ticket",suiteTicket);
        String res = HttpUtil.doJsonPost(GET_SUITE_TOKEN_URL,params,null);
        SuiteTokenVO suiteTokenVO = JSONObject.parseObject(res,SuiteTokenVO.class);
        ParamCheckUtil.objectNull(suiteTokenVO,"suiteTokenVO为空");
        return suiteTokenVO;
    }

    public static PreAuthCodeVO getPreAuthCode(String suiteAccessToken) {
        String res = HttpUtil.doGet(GET_PRE_AUTH_CODE_URL + suiteAccessToken);
        PreAuthCodeVO preAuthCodeVO = JSONObject.parseObject(res,PreAuthCodeVO.class);
        if(preAuthCodeVO != null){
            ParamCheckUtil.notTrue(preAuthCodeVO.getErrcode() == 0,"调用pre_auth_code错误：" + res);
        }
        return preAuthCodeVO;
    }

    public static SetAuthConfigVO setAuthConfig(String suiteAccessToken, SetAuthConfigDTO dto) {
        String res = HttpUtil.doJsonPost(SET_AUTH_CONFIG_URL + suiteAccessToken,dto,null);
        SetAuthConfigVO vo = JSONObject.parseObject(res,SetAuthConfigVO.class);
        if(vo != null){
            ParamCheckUtil.notTrue(vo.getErrcode() == 0,"调用setAuthConfig错误：" + res);
        }
        return vo;
    }

    public static EnterprisesPermanentAuthVO getEnterprisesPermanentAuthCode(String suite_access_token, String auth_code){
        Map<String,String> params = new HashMap<>();
        params.put("auth_code",auth_code);
        String res = HttpUtil.doJsonPost(GET_ENTERPRISES_PERMANENT_AUTH_CODE_URL + suite_access_token,params,null);
        EnterprisesPermanentAuthVO vo = JSONObject.parseObject(res,EnterprisesPermanentAuthVO.class);
        ParamCheckUtil.objectNull(vo,"接口返回为空");
        ParamCheckUtil.notTrue(vo.getErrcode() == null,"接口错误：" + res);
        return vo;
    }

    public static List<GetAppAdminListVO.admin> getAppAdminList(String suite_access_token, String auth_corpid, String agentid) {
        Map<String,String> params = new HashMap<>();
        params.put("auth_corpid",auth_corpid);
        params.put("agentid",agentid);
        String res = HttpUtil.doJsonPost(GET_APP_ADMIN_LIST_URL + suite_access_token,params,null);
        GetAppAdminListVO vo = JSONObject.parseObject(res,GetAppAdminListVO.class);
        ParamCheckUtil.objectNull(vo,"接口返回为空");
        ParamCheckUtil.notTrue(vo.getErrcode() != null && vo.getErrcode() == 0,"接口错误：" + res);
        return vo.getAdmin();
    }

    /**
     * 每个机器人发送的消息不能超过20条/分钟
     * @param webhookurl
     * @param msg
     */
    public static RobotSendMsgVO robotSendMsg(String webhookurl, Object msg){
        String res = HttpUtil.doJsonPost(webhookurl,msg,null);
        log.info("机器人发消息返回：" + res);
        RobotSendMsgVO vo = JSONObject.parseObject(res,RobotSendMsgVO.class);
        ParamCheckUtil.objectNull(vo,"接口返回为空");
        ParamCheckUtil.notTrue(vo.getErrcode() != null && vo.getErrcode() == 0,"接口错误：" + res);
        return vo;
    }

    public static GetVisitUserVO getVisitUser(String suite_access_token, String code) {
        String url = String.format(GET_VISIT_USER_URL,suite_access_token,code);
        String res = HttpUtil.doGet(url);
        GetVisitUserVO vo = JSONObject.parseObject(res,GetVisitUserVO.class);
        if(vo != null){
            ParamCheckUtil.notTrue(vo.getErrcode() != null && vo.getErrcode() == 0,"调用访问用户身份接口错误：" + res);
        }
        return vo;
    }


    /**
     * https://developer.work.weixin.qq.com/document/path/91120
     * 构造网页授权链接
     * @return
     */
    public static String buildPageAuthUrl(String appId,String redirect_uri,String scope,String state){
        return "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=" + UrlUtil.urlEncode(redirect_uri) + "&response_type=code&scope=" + scope + "&state=" + state + "#wechat_redirect";
    }

    /**
     * https://developer.work.weixin.qq.com/document/path/90605
     * 获取企业凭证
     * @return
     */
    public static QYAccessTokenVO getGetQyAccessToken(String suite_access_token,String auth_corpid,String permanent_code){
        Map<String,String> params = new HashMap<>();
        params.put("auth_corpid",auth_corpid);
        params.put("permanent_code",permanent_code);
        String res = HttpUtil.doJsonPost(GET_QY_ACCESS_TOKEN_URL + suite_access_token,params,null);
        QYAccessTokenVO vo = JSONObject.parseObject(res,QYAccessTokenVO.class);
        ParamCheckUtil.objectNull(vo,"接口返回为空");
        ParamCheckUtil.notTrue(vo.getErrcode() == null,"接口错误：" + res);
        return vo;
    }

    /**
     * 获取应用 jsapi_ticket
     * @return
     */
    public static QYWXAppJSAPITicketVO getQYWXAppJSAPITicket(String access_token){
        String url = String.format(GET_QYWX_APP_JSAPI_TICKET_URL,access_token);
        String res = HttpUtil.doGet(url);
        QYWXAppJSAPITicketVO vo = JSONObject.parseObject(res, QYWXAppJSAPITicketVO.class);
        if(vo != null){
            ParamCheckUtil.notTrue(vo.getErrcode() != null && vo.getErrcode() == 0,"获取应用 jsapi_ticket接口错误：" + res);
        }
        return vo;
    }

    /**
     * 获取企业 jsapi_ticket
     * @return
     */
    public static QYWXQYJSAPITicketVO getQYWXQYJSAPITicket(String access_token){
        String url = String.format(GET_QYWX_QY_JSAPI_TICKET_URL,access_token);
        String res = HttpUtil.doGet(url);
        QYWXQYJSAPITicketVO vo = JSONObject.parseObject(res, QYWXQYJSAPITicketVO.class);
        if(vo != null){
            ParamCheckUtil.notTrue(vo.getErrcode() != null && vo.getErrcode() == 0,"获取企业 jsapi_ticket接口错误：" + res);
        }
        return vo;
    }


    /**
     * https://developer.work.weixin.qq.com/document/path/91039
     * 自建应用  accesstoken
     */
    public static AccessTokenVO getAccessToken(String corpid,String corpsecret){
        String url = String.format(QYWX_ACCESS_TOKEN_UTL,corpid,corpsecret);
        String res = HttpUtil.doGet(url);
        AccessTokenVO vo = JSONObject.parseObject(res, AccessTokenVO.class);
        if(vo != null){
            ParamCheckUtil.notTrue(vo.getErrcode() != null && vo.getErrcode() == 0,"获取企业 accesstoken接口错误：" + res);
        }
        return vo;
    }

    /**
     * https://developer.work.weixin.qq.com/document/path/94661
     * 客服列表
     */
    public static KFAccountListVO getKFAccountListVO(String access_token){
        String url = String.format(QYWX_KF_ACCOUNT_LIST_URL,access_token);
        String res = HttpUtil.doGet(url);
        KFAccountListVO vo = JSONObject.parseObject(res, KFAccountListVO.class);
        if(vo != null){
            ParamCheckUtil.notTrue(vo.getErrcode() != null && vo.getErrcode() == 0,"获取客服列表接口错误：" + res);
        }
        return vo;
    }

    /**
     * https://developer.work.weixin.qq.com/document/path/94670
     * @param accessToken
     * @param token
     * @param openKFId
     * @param nextCursor
     * @return
     * 获取客服消息
     */
    public static KFMsgOrEventQYWXDetailVO getKFMSG(String accessToken, String token, String openKFId, String nextCursor) {
        String url = String.format(QYWX_FK_SYNC_MSG_URL,accessToken);
        Map<String,String> params = new HashMap<>();
        if(StringUtil.isNotEmpty(nextCursor)) {
            params.put("cursor", nextCursor);
        }
        params.put("token",token);
        params.put("open_kfid",openKFId);
        String res = HttpUtil.doJsonPost(url,params,null);
        KFMsgOrEventQYWXDetailVO vo = JSONObject.parseObject(res, KFMsgOrEventQYWXDetailVO.class);
        if(vo != null){
            ParamCheckUtil.notTrue(vo.getErrcode() != null && vo.getErrcode() == 0,"获取客服消息的接口错误：" + res);
        }
        return vo;
    }

    /**
     * https://developer.work.weixin.qq.com/document/path/91023
     * @param accessToken
     * @param code
     * @return
     */
    public static GetVisitUserVO getVisitUserForSelfApp(String accessToken, String code) {
        String url = "https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token=%s&code=%s";
        url = String.format(url,accessToken,code);
        String res = HttpUtil.doGet(url);
        GetVisitUserVO vo = JSONObject.parseObject(res, GetVisitUserVO.class);
        ParamCheckUtil.objectNull(vo,"接口返回为空");
        ParamCheckUtil.notTrue(vo.getErrcode() != null && vo.getErrcode() == 0,"接口错误：" + res);
        return vo;
    }

    public static QwDeptListVO getDeptList(String accessToken, String id) {
        String url = null;
        if(StringUtil.isNotEmpty(id)){
            url = "https://qyapi.weixin.qq.com/cgi-bin/department/simplelist?access_token=" + accessToken + "&id=" + id;
        }else{
            url = "https://qyapi.weixin.qq.com/cgi-bin/department/simplelist?access_token=" + accessToken;
        }
        String res = HttpUtil.doGet(url);
        QwDeptListVO vo = JsonUtil.parseJson(res,QwDeptListVO.class);
        ParamCheckUtil.objectNull(vo,"接口返回为空");
        ParamCheckUtil.notTrue(vo.getErrcode() != null && vo.getErrcode() == 0,"接口错误：" + res);
        return vo;
    }

    /**
     * https://developer.work.weixin.qq.com/document/path/96067
     * @param contactAccessToken
     * @param nextCursor
     * @return
     */
    public static QwDeptUserVO getDeptUser(String contactAccessToken, String nextCursor) {
        String url = "https://qyapi.weixin.qq.com/cgi-bin/user/list_id?access_token=" + contactAccessToken;
        Map<String,String> params = new HashMap<>();
        if(StringUtil.isNotEmpty(nextCursor)){
            params.put("cursor",nextCursor);
        }
        String res = HttpUtil.doJsonPost(url,params,null);
        QwDeptUserVO vo = JSONObject.parseObject(res,QwDeptUserVO.class);
        ParamCheckUtil.objectNull(vo,"接口返回为空");
        ParamCheckUtil.notTrue(vo.getErrcode() != null && vo.getErrcode() == 0,"接口错误：" + res);
        return vo;
    }
}
